package net.microlinktech.testing.ui;

import gnu.io.CommPortIdentifier;
import gnu.io.PortInUseException;
import gnu.io.UnsupportedCommOperationException;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.TooManyListenersException;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;

import net.microlinktech.testing.bean.Meter;
import net.microlinktech.testing.packet.CommSerialPort;
import net.microlinktech.testing.serial.SerialPort;
import org.apache.commons.lang3.StringUtils;

import net.microlinktech.testing.bean.PortOption;
import net.microlinktech.testing.codec.StringCoder;
import net.microlinktech.testing.codec.StringSubstring;
import net.microlinktech.testing.ui.celleditor.HexTextFieldEditor;
import net.microlinktech.testing.ui.celleditor.TextFieldEditor;
import net.microlinktech.testing.ui.dialog.MessageDialog;
import net.microlinktech.testing.ui.event.GetDateTime;
import net.microlinktech.testing.ui.event.MeterEvent;
import net.microlinktech.testing.ui.model.MeterTableModel;
import net.microlinktech.testing.ui.table.TableFactory;
import net.microlinktech.testing.ui.table.renderer.HorizontalAlignmentCellRenderer;
import com.jgoodies.forms.factories.FormFactory;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.RowSpec;
import com.jidesoft.plaf.LookAndFeelFactory;

import javax.swing.UIManager;

public class ReadMeter {

	private static final String SER_FILE_NAME = "meter.data";

	private Timer timer;

	private RemindTask remindTask;

	private SerialPort serialPortSend;

	private JTable friends;

	private MeterTableModel tableModel;

	private List<PortOption> portOptions;

	private CommSerialPort commSerialPort;

	private MeterEvent meterEvent;

	String load1, load2, load3;
	double power1 = 0;
	double power2 = 0;
	double power3 = 0;

	private JFrame frame;
	private JButton btnNewButton;
	private JComboBox<Object> comboBox;
	private JComboBox<Integer> comboBox_1;
	private JLabel label;
	private JLabel lblNewLabel_6;
	private JButton sendBtn;
	private JButton sendCloseBtn;
	public static JTextArea textArea;

	private JPanel panel;

	private File meterDataFile;
	private JButton btnNewButton_1;
	private JButton btnNewButton_2;
	private JButton button_2;

	private StringSubstring stringSubString;
	private JLabel lblNewLabel;
	private JComboBox<Object> comboBox_3;
	private JLabel lblNewLabel_1;
	private JComboBox<Object> comboBox_2;
	private JLabel label_1;

	private JButton btnCancel;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		LookAndFeelFactory.installDefaultLookAndFeelAndExtension();

		@SuppressWarnings("unused")
		GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();

		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					ReadMeter window = new ReadMeter();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	
	
	
	/**
	 * Create the application.
	 */
	public ReadMeter() {
		initialize();
		stringSubString = new StringSubstring();
		timer = new Timer();
		meterEvent = new MeterEvent();
	}

	
	
	/**
	 * @author c000753
	 *
	 */
	class RemindTask extends TimerTask {
		public void run() {
			List<Meter> meters = tableModel.getMeters();
			for (Meter meter : meters) {
				meterEvent.updateMeter(meter);
			}
			tableModel.fireTableDataChanged();
		}
	}

	
	
	/**
	 * Initialize the contents of the frame.
	 */
	@SuppressWarnings("unchecked")
	private void initialize() {
		portOptions = new ArrayList<>();
		serialPortSend = new SerialPort();
		@SuppressWarnings("rawtypes")
		Enumeration en = CommPortIdentifier.getPortIdentifiers();
		while (en.hasMoreElements()) {
			CommPortIdentifier portId = (CommPortIdentifier) en.nextElement();
			if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
				portOptions.add(new PortOption(portId));
			}
		}
		frame = new JFrame();
		frame.setTitle("虚拟电表");
		frame.setIconImage(Toolkit.getDefaultToolkit().getImage(ReadMeter.class.getResource("/net/microlinktech/resources/concent.png")));
		frame.setBounds(100, 100, 725, 300);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setExtendedState(JFrame.MAXIMIZED_BOTH); // 最大化
		frame.setLocation(20, 50);
		frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				try {
					save();
				} catch (Exception ex) {
					ex.printStackTrace();
				}
				System.exit(0);
			}
		});
		frame.getContentPane().setLayout(new FormLayout(new ColumnSpec[] { ColumnSpec.decode("20px"), FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("100px"), FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("110px"), FormFactory.RELATED_GAP_COLSPEC, FormFactory.DEFAULT_COLSPEC, FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("120px"), FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("center:60px"), FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("80px"), FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("100px"), FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("100px"), FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("637px:grow"), FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("20px"), }, new RowSpec[] { FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC, RowSpec.decode("default:grow"), RowSpec.decode("20px"), FormFactory.RELATED_GAP_ROWSPEC, RowSpec.decode("100px:grow"), FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC, }));

		lblNewLabel_6 = new JLabel("端口号：");
		frame.getContentPane().add(lblNewLabel_6, "3, 3, right, default");

		comboBox = new JComboBox<Object>(portOptions.toArray());
		// comboBox = new JComboBox();
		frame.getContentPane().add(comboBox, "5, 3, fill, default");
		label = new JLabel("波特率：");
		frame.getContentPane().add(label, "7, 3, right, default");
		Integer[] rate = { 600, 1200, 2400, 4800, 9600, 19200 };
		comboBox_1 = new JComboBox<Integer>(rate);
		// comboBox_1 = new JComboBox<Integer>();
		frame.getContentPane().add(comboBox_1, "9, 3, fill, fill");

		lblNewLabel_1 = new JLabel("校验位:");
		frame.getContentPane().add(lblNewLabel_1, "11, 3, right, default");

		String[] parity = { "无", "偶校验", "奇校验" };
		comboBox_2 = new JComboBox<Object>(parity);
		frame.getContentPane().add(comboBox_2, "13, 3, center, default");

		sendBtn = new JButton("打开串口");
		sendBtn.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				PortOption portOption = (PortOption) comboBox.getSelectedItem();
				serialPortSend.setPortName(portOption.getName());
				serialPortSend.setPortIdentifier(portOption.getPortId());
				serialPortSend.setBaudRate((Integer) comboBox_1.getSelectedItem());
				serialPortSend.setDataBit(gnu.io.SerialPort.DATABITS_8);
				serialPortSend.setStopBit(gnu.io.SerialPort.STOPBITS_1);
				int Intparity = 0;
				if (comboBox_2.getSelectedItem().equals("无")) {
					Intparity = 0;
				} else if (comboBox_2.getSelectedItem().equals("奇校验")) {
					Intparity = 1;
				} else if (comboBox_2.getSelectedItem().equals("偶校验")) {
					Intparity = 2;
				}
				serialPortSend.setParityBit(Intparity);
				String error = "";
				try {
					gnu.io.SerialPort port = (gnu.io.SerialPort) serialPortSend.getPortIdentifier().open(serialPortSend.getPortName(), serialPortSend.getTimeout());
					// 设置串口通讯参数：波特率、数据位、停止位、奇偶校验
					port.setSerialPortParams(serialPortSend.getBaudRate(), serialPortSend.getDataBit(), serialPortSend.getStopBit(), serialPortSend.getParityBit());
					commSerialPort = new CommSerialPort(port, serialPortSend.getDelayRead(), tableModel);
					// testingDevicePort.setSendSerialPort(commSerialPort);
					sendCloseBtn.setEnabled(true);
					sendBtn.setEnabled(false);
					// profileService.updateProfileContent(SerialUse.SEND.name(),
					// serialPortSend.getPortName());
				} catch (PortInUseException e1) {
					error = "此串口正在使用中";
				} catch (IOException e1) {
					error = "打开串口失败";
					e1.printStackTrace();
				} catch (TooManyListenersException e1) {
					error = "打开串口失败";
				} catch (UnsupportedCommOperationException e1) {
					error = "打开串口失败";
				}
				if (StringUtils.isNotBlank(error)) {
					MessageDialog.showError(error);
				}
			}

		});
		frame.getContentPane().add(sendBtn, "15, 3, center, center");

		sendCloseBtn = new JButton("关闭串口");
		sendCloseBtn.setEnabled(false);
		frame.getContentPane().add(sendCloseBtn, "17, 3, center, center");
		sendCloseBtn.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				sendCloseBtn.setEnabled(false);
				sendBtn.setEnabled(true);
				commSerialPort.close();
			}

		});

		String[] baudRate = { "请选择波特率", "600", "1200", "2400", "4800", "9600", "19200", "38400" };

		lblNewLabel = new JLabel("设置模块波特率：");
		frame.getContentPane().add(lblNewLabel, "3, 5, right, default");
		comboBox_3 = new JComboBox<Object>(baudRate);
		frame.getContentPane().add(comboBox_3, "5, 5, fill, default");

		btnNewButton = new JButton("启动");
		btnNewButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnNewButton.setEnabled(false);
				btnCancel.setEnabled(true);
				remindTask = new RemindTask();
				timer.schedule(remindTask, 1000, 3000);
			}
		});
		frame.getContentPane().add(btnNewButton, "9, 5, center, center");

		btnCancel = new JButton("停止");
		btnCancel.setEnabled(false);
		btnCancel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					if (remindTask != null) {
						btnCancel.setEnabled(false);
						btnNewButton.setEnabled(true);
						remindTask.cancel();
					}
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}
		});
		frame.getContentPane().add(btnCancel, "11, 5, center, center");

		label_1 = new JLabel("");
		new GetDateTime(label_1);
		label_1.setFont(new Font("微软雅黑", Font.PLAIN, 18));
		frame.getContentPane().add(label_1, "15, 5, 5, 1, fill, fill");

		panel = new JPanel();
		frame.getContentPane().add(panel, "3, 7, 17, 1, fill, fill");
		panel.setLayout(new BorderLayout(0, 0));

		panel.add(createContentPanel(), BorderLayout.CENTER);

		textArea = new JTextArea();
		JScrollPane scrollPane = new JScrollPane(textArea);
		frame.getContentPane().add(scrollPane, "3, 10, 17, 1, fill, fill");

		// frame.setSize(1400, 600);

		try {
			meterDataFile = new File(SER_FILE_NAME);
			InputStream ris = new FileInputStream(meterDataFile);
			ObjectInputStream is = new ObjectInputStream(ris);
			List<Meter> tempList = (List<Meter>) is.readObject();// 从流中读取List的数据
			tableModel.setMeters(tempList);
			is.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

	}

	public JComponent createContentPanel() {
		JPanel contentPanel = new JPanel(new BorderLayout(0, 0));
		contentPanel.setBorder(new EmptyBorder(2, 2, 2, 2));

		tableModel = new MeterTableModel();
		tableModel.init();
		friends = TableFactory.getGeneralConfigTable(tableModel);
		friends.setBackground(UIManager.getColor("Button.highlight"));
		friends.setPreferredScrollableViewportSize(new Dimension(600, 100));// 设置表格的大小
		friends.setRowMargin(5);// 设置相邻两行单元格的距离

		friends.getTableHeader().setReorderingAllowed(false); // 不可整列移动
		friends.getTableHeader().setResizingAllowed(true); // 不可拉动表格

		friends.getColumnModel().getColumn(1).setCellEditor(new TextFieldEditor());
		friends.getColumnModel().getColumn(2).setCellEditor(new TextFieldEditor());
		friends.getColumnModel().getColumn(3).setCellEditor(new HexTextFieldEditor(6));
		// friends.getColumnModel().getColumn(2).setCellEditor(new
		// TextFieldEditor());

		friends.getColumnModel().getColumn(0).setCellRenderer(new HorizontalAlignmentCellRenderer(SwingConstants.CENTER));
		friends.getColumnModel().getColumn(1).setCellRenderer(new HorizontalAlignmentCellRenderer(SwingConstants.CENTER));
		friends.getColumnModel().getColumn(2).setCellRenderer(new HorizontalAlignmentCellRenderer(SwingConstants.CENTER));
		friends.getColumnModel().getColumn(3).setCellRenderer(new HorizontalAlignmentCellRenderer(SwingConstants.CENTER));
		friends.getColumnModel().getColumn(4).setCellRenderer(new HorizontalAlignmentCellRenderer(SwingConstants.CENTER));
		friends.getColumnModel().getColumn(5).setCellRenderer(new HorizontalAlignmentCellRenderer(SwingConstants.CENTER));
		friends.getColumnModel().getColumn(6).setCellRenderer(new HorizontalAlignmentCellRenderer(SwingConstants.CENTER));
		friends.getColumnModel().getColumn(7).setCellRenderer(new HorizontalAlignmentCellRenderer(SwingConstants.CENTER));

		contentPanel.add(new JScrollPane(friends), BorderLayout.CENTER);

		JToolBar toolBar = new JToolBar();
		contentPanel.add(toolBar, BorderLayout.NORTH);
		toolBar.setFloatable(false);

		JButton button = new JButton("新建");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				tableModel.add(meterEvent.createMeter());
			}
		});
		toolBar.add(button);

		JButton button_1 = new JButton("删除");
		button_1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int selectedRow = friends.getSelectedRow();
				if (selectedRow >= 0) {
					try {
						int previewRow = selectedRow - 1;
						friends.changeSelection(previewRow, 0, false, false);
						if (previewRow == -1) {
							friends.changeSelection(selectedRow + 1, 0, false, false);
						}
						tableModel.removeRow(selectedRow);
					} catch (Exception e1) {
						e1.printStackTrace();
					}
				} else {
					MessageDialog.showInformation("请选择需要删除的纪录");
				}
			}
		});
		toolBar.add(button_1);

		JButton button_4 = new JButton("保存");
		button_4.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					save();
					MessageDialog.showInformation("保存成功");
				} catch (Exception ex) {
					ex.printStackTrace();
					MessageDialog.showError("保存失败");
				}

			}
		});
		toolBar.add(button_4);

		btnNewButton_2 = new JButton("设置地址");
		btnNewButton_2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int selectedRow = friends.getSelectedRow();
				if (selectedRow >= 0) {
					if (!sendBtn.isEnabled()) {
						Meter meter = tableModel.getMeter(selectedRow);
						if (meter.getMeterAddress() != null) {
							byte boardNum = (byte) meter.getBoardNum();
							byte dauNum = (byte) meter.getDauNum();
							byte[] dauAddress = { boardNum, dauNum };
							String address = stringSubString.getStringByLength(meter.getMeterAddress(), 12);
							byte[] meterAddress = StringCoder.hexStringToByte(address.substring(10, 12) + address.substring(8, 10) + address.substring(6, 8) + address.substring(4, 6) + address.substring(2, 4) + address.substring(0, 2));
							byte cmd = 0x01;
							byte[] dataTmp = commSerialPort.AutoMeterFrame(dauAddress, cmd, meterAddress);
							commSerialPort.send("发送设置地址的帧:   ", dataTmp);
							meter.setAddressState("成功");

						} else {
							MessageDialog.showInformation("请填写电表地址！");
						}

					} else {
						MessageDialog.showInformation("请先打开串口！");
					}
				} else {
					MessageDialog.showInformation("请选择需要设置地址的帧");
				}
			}
		});
		toolBar.add(btnNewButton_2);

		button_2 = new JButton("事件上报");
		button_2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int selectedRow = friends.getSelectedRow();
				if (selectedRow >= 0) {
					if (!sendBtn.isEnabled()) {
						try {
							Meter meter = tableModel.getMeter(selectedRow);
							byte boardNum = (byte) meter.getBoardNum();
							byte dauNum = (byte) meter.getDauNum();
							byte[] dauAddress = { boardNum, dauNum };
							byte cmd = 0x02;
							byte[] meterAddress = {};
							byte[] dataTmp = commSerialPort.AutoMeterFrame(dauAddress, cmd, meterAddress);
							commSerialPort.send("发送事件上报的帧:   ", dataTmp);
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					} else {
						MessageDialog.showInformation("请先打开串口！");
					}
				} else {
					MessageDialog.showInformation("请选择需要进行事件上报的帧");
				}
			}
		});
		toolBar.add(button_2);

		btnNewButton_1 = new JButton("设置波特率");
		btnNewButton_1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int selectedRow = friends.getSelectedRow();
				if (selectedRow >= 0) {
					if (!sendBtn.isEnabled()) {
						Meter meter = tableModel.getMeter(selectedRow);
						byte boardNum = (byte) meter.getBoardNum();
						byte dauNum = (byte) meter.getDauNum();
						byte[] dauAddress = { boardNum, dauNum };
						String baudRate = (String) comboBox_3.getSelectedItem();
						byte cmd = 0x03;
						String message = "发送设置波特率的帧为：   ";
						if (baudRate.equals("600")) {
							byte[] dataTmp = { 0x01 };
							commSerialPort.send(message, commSerialPort.AutoMeterFrame(dauAddress, cmd, dataTmp));
						} else if (baudRate.equals("1200")) {
							byte[] dataTmp = { 0x02 };
							commSerialPort.send(message, commSerialPort.AutoMeterFrame(dauAddress, cmd, dataTmp));
						} else if (baudRate.equals("2400")) {
							byte[] dataTmp = { 0x03 };
							commSerialPort.send(message, commSerialPort.AutoMeterFrame(dauAddress, cmd, dataTmp));
						} else if (baudRate.equals("4800")) {
							byte[] dataTmp = { 0x04 };
							commSerialPort.send(message, commSerialPort.AutoMeterFrame(dauAddress, cmd, dataTmp));
						} else if (baudRate.equals("9600")) {
							byte[] dataTmp = { 0x05 };
							commSerialPort.send(message, commSerialPort.AutoMeterFrame(dauAddress, cmd, dataTmp));
						} else if (baudRate.equals("19200")) {
							byte[] dataTmp = { 0x06 };
							commSerialPort.send(message, commSerialPort.AutoMeterFrame(dauAddress, cmd, dataTmp));
						} else {
							MessageDialog.showWarn("请选择您需要设置的波特率！");
						}
					} else {
						MessageDialog.showInformation("请先打开串口！");
					}
				} else {
					MessageDialog.showInformation("请选择需要设置波特率的帧");
				}
			}
		});
		toolBar.add(btnNewButton_1);

		return contentPanel;
	}

	private void save() throws Exception {
		ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(meterDataFile));
		os.writeObject(tableModel.getMeters());// 将List列表写进文件
		os.close();
	}

}
